package com.mango.iot.gateway.coap.server.resource;

import cn.hutool.core.util.IdUtil;
import com.mango.iot.gateway.coap.common.CoapResourceConst;
import com.mango.iot.gateway.coap.redis.RedisUtils;
import com.mango.iot.gateway.coap.server.request.CoapAuthRequest;
import com.mango.iot.gateway.coap.server.response.CoapAuthResponse;
import com.mango.iot.gateway.coap.utils.JacksonUtil;
import com.mango.iot.gateway.coap.utils.SignUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.californium.core.CoapResource;
import org.eclipse.californium.core.coap.CoAP;
import org.eclipse.californium.core.server.resources.CoapExchange;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 设备认证 API
 *
 * @author liangfeihu
 * @number 53669
 * @since 2021/4/27 下午3:21
 */
@Slf4j
@Component
public class AuthResource extends CoapResource {

    @Autowired
    private RedisUtils redisUtils;

    public AuthResource() {
        super(CoapResourceConst.AUTH);
        getAttributes().setTitle("Auth Resource");
    }

    /**
     * 认证接口只支持POST请求，
     * 其他请求方式不支持，默认返回CoAP.ResponseCode.METHOD_NOT_ALLOWED
     *
     * @param exchange
     */
    @Override
    public void handlePOST(CoapExchange exchange) {
        log.info("[AuthResource] request body={}", exchange.getRequestText());
        try {
            CoapAuthRequest request = JacksonUtil.json2Obj(exchange.getRequestText(), CoapAuthRequest.class);
            if (request == null || StringUtils.isBlank(request.getProductKey()) || StringUtils.isBlank(request.getDeviceNo())) {
                exchange.respond(CoAP.ResponseCode.UNSUPPORTED_CONTENT_FORMAT);
                return;
            }

            String deviceSecret = getValidDevice(request.getProductKey(), request.getDeviceNo());

            Map<String, Object> params = JacksonUtil.json2Obj(exchange.getRequestText(), HashMap.class);
            if (params != null && SignUtil.verifySign(params, deviceSecret)) {
                String redisKey = request.getProductKey() + request.getDeviceNo();
                String token = getTokenFromCache(redisKey);
                redisUtils.set(redisKey, token, CoapResourceConst.AUTH_TOKEN_EXPIRE_TIME);

                CoapAuthResponse authResponse = new CoapAuthResponse();
                authResponse.setToken(token);
                exchange.respond(JacksonUtil.obj2Json(authResponse));
            } else {
                exchange.respond(CoAP.ResponseCode.UNAUTHORIZED);
            }
        } catch (Exception e) {
            log.error("auth error={}", e);
            exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR);
        }
    }

    private String getTokenFromCache(String redisKey) {
        Object value = redisUtils.get(redisKey);
        if (value != null) {
            return value.toString();
        }
        return IdUtil.fastSimpleUUID();
    }

    /**
     * <pre>
     * 获取设备密钥
     * </pre>
     *
     * @param productKey
     * @param deviceNo   设备编号
     * @return java.lang.String
     */
    private String getValidDevice(String productKey, String deviceNo) {
        return null;
    }

}
